/********************************************************************************
 * Project Name		[JavaSE_Fundamentals]
 * File Name     	[SecureBank1.java]
 * Creation Date 	[2015-01-01]
 * 
 * Copyright© ge.y.yang@gmail.com All Rights Reserved
 * 
 * Work hard, play harder, think big and keep fit
 ********************************************************************************/
package thread.synchronization;

/**
 * @author 不落的太阳(Sean Yang aka ShortPeace)
 * @version 1.0
 * @since jdk 1.8
 * 
 */
public class SecureBank1 implements Bank {

	private final double[] accounts;

	public SecureBank1(int n, double initialBalance) {
		accounts = new double[n];
		for (int i = 0; i < n; i++) {
			accounts[i] = initialBalance;
		}
	}

	@Override
	public synchronized void transfer(int fromAccount, int toAccount, double amount) {
		try {
			while (accounts[fromAccount] < amount) {
				wait(); // 当余额不足时当前线程进入等待
			}

			accounts[fromAccount] -= amount;
			System.out.printf(" %10.2f from %d to %d", amount, fromAccount, toAccount);
			accounts[toAccount] += amount;
			System.out.printf(" Total Balance: %10.2f%n", getTotalBalance());
			// 重新激活因余额不足而等待的所有线程
			notifyAll();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}

	public synchronized double getTotalBalance() {
		double sum = 0;
		for (double d : accounts) {
			sum += d;
		}
		return sum;
	}

	@Override
	public int getAccountNumber() {
		return accounts.length;
	}

	public static void main(String[] args) {
		int NACCOUNTS = 100;
		double INITIAL_BALANCE = 1000;

		Bank bank = new SecureBank1(NACCOUNTS, INITIAL_BALANCE);
		for (int i = 0; i < NACCOUNTS; i++) {
			MoneyTransfer r = new MoneyTransfer(bank, i, INITIAL_BALANCE);
			Thread t = new Thread(r);
			t.start();
		}
	}
}
